<?php

class FeedController
{
    private $feedModel;
    private $followModel;
    private $autoUidModel;
    private static $modelPool;
    private $diaryListModel;
    private $commentModel;
    private $diaryListCacheModel;
    private $likeModel;
    private $userStatisticsModel;
    private static $bodyInfo = NULL;
    
    function __construct()/*{{{*/
    {
        $this->feedModel            =   new FeedModel();
        $this->followModel          =   new FollowModel();
        $this->autoUidModel         =   new AutoUidModel();
        $this->userStatisticsModel  =   new UserStatisticsModel();
        $this->diaryListModel       =   new DiaryListModel();
        $this->commentModel         =   new CommentModel();
        $this->diaryListCacheModel  =   new DiaryListCacheModel();
        $this->likeModel            =   new LikeModel();
    }/*}}}*/
    
    /**
     * 发动态、通知及更新时间线
     * @param unknown $feedInfo
     * @return boolean
     */
    public function postFeed($feedInfo) {
        // check params
        if (empty($feedInfo['uid']) ||  empty($feedInfo['type'])) {
            AC::$errorNo    =   'FEC001';
            return  FALSE;
        }
        
        // 更新时间线
        if (AC::REDIS_WRITE && $feedInfo['type'] == AC::FEED_DIARY || AC::REDIS_WRITE && $feedInfo['type'] == AC::FEED_REPOST){
            $jobdata = array(
                    "uid" =>    $feedInfo['uid'],
                    "bodyId" => $feedInfo['bodyId']
            );
            $jobkeyid = $feedInfo['uid']."-".$feedInfo['bodyId'];
            RedisPool::addGearmanJob("postdiary", $jobdata, $jobkeyid);
        }
        
        $sendResult     =   $this->feedModel->setFeedInfo($feedInfo);
        return  TRUE;
    }

    public function getFeedList($feedInfo)/*{{{*/
    {
        if (empty($feedInfo['uid']))
        {
            AC::$errorNo    =   'FEC003';
            return  FALSE;
        }

        # feedList  /*{{{*/
        if (empty($feedInfo['listMode']))
        {   
            $feedList       =   $this->feedModel->getFeedList($feedInfo);
        }
        else
        {
            if (empty($feedInfo['id']))
            {
                AC::$errorNo    =   'FEC007';
                return  FALSE;
            }

            if ('up' == $feedInfo['listMode'])
            {
                $feedList   =   $this->feedModel->getFeedListUp($feedInfo);
            }
            else
            {
                $feedList   =   $this->feedModel->getFeedListDown($feedInfo);
            }
        }/*}}}*/
        if (empty($feedList) || !is_array($feedList))   return  NULL;

        foreach ($feedList  as  &$feedDetail)
        {
            $feedDetail['detail']           =    $this->getFeedDetail($feedDetail);
            $feedDetail['retweeted_status'] =    $this->diaryListModel->manipulationListData($feedDetail['detail']);
        }
        $this->userStatisticsModel->resetNewCommentTimesStatistics($feedInfo);
        return  $feedList;
    }/*}}}*/
    
    /**
     * 好友的动态
     * @param unknown $feedInfo
     * @return boolean|NULL|Ambigous <boolean, unknown, multitype:>
     */
    public function getUserFeedList($feedInfo)/*{{{*/
    {
        if (empty($feedInfo['uid']))
        {
            AC::$errorNo    =   'FEC003';
            return  FALSE;
        }
        $uids = array();
        if (isset($feedInfo['followfeed'])){
            unset($feedInfo['mefeed']);
        }
        if (isset($feedInfo['mefeed'])){
            unset($feedInfo['followfeed']);
            // 重置关于我的轮询
            $this->userStatisticsModel->resetNewLikeMeTimesStatistics($feedInfo);
        }
        
        if (!isset($feedInfo['followfeed']) && isset($feedInfo['mefeed'])){
            // 获取新的通知,暂屏蔽
            $feedList       =   $this->feedModel->getUserNoticeListFromRedis($feedInfo);
	    
            //官方公告轮询数字更新
            $this->feedModel->UpdateAnnounceCount($feedInfo['uid']);
	    
            // 重建并更新动态刷新时间
            $user_cache = $this->diaryListCacheModel->getUserFeedMeCache($feedInfo['uid']);
            if (count($feedList) < 1 || $user_cache['fdme_upt'] < 1){
                RedisPool::addGearmanJob("feedme_timeline", array("uid"=>$feedInfo['uid']), $feedInfo['uid']);
                $this->diaryListCacheModel->updateUserFeedMeTime($feedInfo['uid']);
            }
        }else{
            $feedList       =   $this->feedModel->getUserFeedListFromRedis($feedInfo);

            // 重建并更新动态刷新时间
            $user_cache = $this->diaryListCacheModel->getUserFeedCache($feedInfo['uid']);
            if (count($feedList) < 1 || $user_cache['feed_upt'] < 1){
                RedisPool::addGearmanJob("feed_timeline", array("uid"=>$feedInfo['uid']), $feedInfo['uid']);
                $this->diaryListCacheModel->updateUserFeedTime($feedInfo['uid']);
            }
        }
        if (empty($feedList) || !is_array($feedList))   return  NULL;
        
        $result = array();
        foreach ($feedList  as  $k => &$feedDetail) {
            $feedDetail    =  $this->feedModel->rebuildFeedList($feedDetail);

            if($feedDetail['type']==AC::FEED_REMOVEFOLLOW && AC::$removeFollowVersion){
				unset($feedDetail);
            	unset($feedList[$k]);
            	continue;
			}
            if ($feedDetail['type'] == AC::FEED_FOLLOW || $feedDetail['type'] == AC::FEED_REMOVEFOLLOW ){
                $feedDetail['detail']      =   (Object) array();
                $result[]  = $feedDetail;
                continue;
            }
            
            $redisDiary = $this->diaryListModel->getDiaryInfoByBodyId($feedDetail['bodyId']);
            if (empty($redisDiary) && !is_array($redisDiary)){
                $feedDetail['authorUid']        =    $feedDetail['eUid'];
                $feedDetail['detail']           =    $this->feedModel->buildFeedItem($feedDetail);
                unset($feedDetail['authorUid']);
                $feedDetail['retweeted_status'] =    (Object) array();
                $result[]  = $feedDetail;
                continue;
            }
            $feedDetail['detail']           =    $this->diaryListModel->buildDiaryListItem($redisDiary);
            $feedDetail['retweeted_status'] =    $this->diaryListModel->manipulationListData($feedDetail['detail']);
            $feedDetail['detail']['id']     =    $feedDetail['id'];
            $result[]  = $feedDetail;
        }
        $feedList = array_values($feedList);
        // 清空轮询 
        $this->userStatisticsModel->resetNewCommentTimesStatistics($feedInfo);
        return  $feedList;
    }/*}}}*/
    
    /**
     * 获取列表
     * @param unknown $param
     * @return unknown
     */
    public function getAnnounceList($param){
        $uid = intval($param['uid']);
    	if(empty($uid)){
            AC::$errorNo = 'FEC003';
            return false;
    	}
    	
    	list($id,$start,$length) = UK::assemblePageData($param);
    	
    	$feedIds = $this->feedModel->getAnnounceList($id, $length);
    	
    	$list = $this->getAnnounceListData($feedIds);
    	if (empty($list)) return (Object) array();
    	
    	//更新查看公告时间和轮询数字
    	$this->feedModel->UpdateAnnounceData($uid);
        
    	$result = array(
    	    'list'     =>  $list,
    	    'counts'   =>  count($list)
    	);
    	
    	return $result;
    }
    
    private function getAnnounceListData ($feedIds) {
        if (empty($feedIds)) return array();
        
        $list = array();
        if($feedIds){
            foreach ($feedIds as $fid){
                $tmp = $this->diaryListCacheModel->getFeedInfoCache($fid);
                if(empty($tmp)) continue;
        
                $list[] = $this->feedModel->rebuildNoticeData($tmp);
            }
        }
        
        return $list;
    }
   
   /*
     * 关注列表,关注用户以及自己发表的日志
     * @param $feedInfo[uid]
     * @return boolean|NULL|array
     */
    public function getTimeline($feedInfo)/*{{{*/
    {
        if (empty($feedInfo['uid']))
        {
            AC::$errorNo    =   'FEC003';
            return  FALSE;
        }
       
        if (empty($feedInfo['id'])) $feedInfo['id'] = 0;
        
        $timeLineList = $this->diaryListCacheModel->getUserTimeline($feedInfo['uid'], $feedInfo['id'], intval($feedInfo['start']), intval($feedInfo['length']));
        
        if (count($timeLineList) < 1){
            
            RedisPool::addGearmanJob("timeline", array("uid"=>$feedInfo['uid']), $feedInfo['uid']);
            //$this->feedModel->statRebuildTimeline($feedInfo['uid'], AC::FEED_DIARY);
        }
        if (empty($timeLineList) || !is_array($timeLineList))   return  NULL;
        
        $num = 0;
        $feedList = array();
        foreach ($timeLineList as $bodyId){
			$tmp = $this->diaryListModel->getDiaryInfoByBodyId($bodyId);
			if(empty($tmp) || intval($tmp['secret'])>0 || intval($tmp['status'])>0){
                 $num++;
                 continue;
             }
             $tmp['id']    =    $tmp['bodyId'];
             $feedList[]  = $this->feedModel->square($tmp);
        }

        // 3条以上空数据重建时间线
        if ($num > 3){
            RedisPool::addGearmanJob("timeline", array("uid"=>$feedInfo['uid']), $feedInfo['uid']);
        }
	
        //官方公告轮询数字更新
        $this->feedModel->UpdateAnnounceCount($feedInfo['uid']);
	
        // 更新用户活跃时间
        $this->autoUidModel->updateUserLastActivity($feedInfo['uid']);
        
        return  $feedList;
    }
    
    /**
     * 喜欢我的列表
     * 注意,在调用getLikeMeFeed 方法时:
     * 第一个参数是查询的uid,第二个是提及我在feed里面的类型为18,
     * @param $feedInfo[uid]
     * @return boolean|NULL|array
     */
    public function getLikesMe($feedInfo){
        
        if (empty($feedInfo['uid']))
        {
            AC::$errorNo    =   'FEC003';
            return  FALSE;
        }
        $feedList   =   $this->likeModel->getLikeMeListDown($feedInfo);
        if (empty($feedList) || !is_array($feedList))   return  NULL;
    
        foreach ($feedList  as  &$feedDetail){
            $redisDiary =  $this->diaryListModel->getDiaryInfoByBodyId($feedDetail['bodyId']);
            if (is_array($redisDiary)){
                $feedDetail =  $this->feedModel->likesData($redisDiary, $feedDetail);
                continue;
            }
             $feedDetail = $this->feedModel->feedLikesData($feedDetail);
         }
         
        return  $feedList;
    }
    
    /**
     * 评论我的信息
     * 注意,在调用getCommentMeList 方法时:
     * 第一个参数是查询的uid,第二个是feed里面的类型为17,
     * @param $feedInfo[uid]
     * @return boolean|NULL|array
     */
    public function getCommentsToMe($feedInfo)/*{{{*/
    {
        if (empty($feedInfo['uid']))
        {
            AC::$errorNo    =   'FEC003';
            return  FALSE;
        }
        // 重置评论我的轮询
        $this->userStatisticsModel->resetNewCommentMeTimesStatistics($feedInfo);
        $feedList =   $this->commentModel->getCommenMe($feedInfo);
        
        if (empty($feedList)  ||  !is_array($feedList)) return  NULL;
        $commentList    =  array();
        foreach ($feedList    as  $feedDetail)
        {
            $feedDetail['nickname']   = AC::$hostUserBaseInfo['nickname'];
            if (!empty(self::$bodyInfo[$feedDetail['bodyId']]) && is_array(self::$bodyInfo[$feedDetail['bodyId']])){
                $feedDetail                   =    $this->feedModel->rebuildCommentMeData($feedDetail, self::$bodyInfo[$feedDetail['bodyId']]);
                $commentList[]                =    $feedDetail;
                continue;
            }
            
            $redisDiary =  $this->diaryListModel->getDiaryInfoByBodyId($feedDetail['bodyId']);
            self::$bodyInfo[$feedDetail['bodyId']] = $redisDiary;
            
            if (!empty($redisDiary) || is_array($redisDiary)){
                $feedDetail                   =    $this->feedModel->rebuildCommentMeData($feedDetail, $redisDiary);
                $commentList[]                =    $feedDetail;
                continue;
            }
            $feedDetail                      =    $this->feedModel->rebuildCommentMeData($feedDetail);
            $feedDetail['detail']            =    $redisDiary;
            $commentList[]                   =    $feedDetail;
        }
        return  $commentList;
    }/*}}}*/
    
    /**
     * 我评论的信息
     * 注意,在调用getMeCommentList 方法时:
     * 第一个参数是查询的uid,第二个feed里面的类型为17,
     * @param $feedInfo[uid]
     * @return boolean|NULL|array
     */
    public function getCommentsByMe($feedInfo)/*{{{*/
    {
        if (empty($feedInfo['uid']))
        {
            AC::$errorNo    =   'FEC003';
            return  FALSE;
        }
        // 重置评论我的轮询
        $this->userStatisticsModel->resetNewCommentMeTimesStatistics($feedInfo);
        $feedList =   $this->commentModel->getMeCommen($feedInfo);
        if (empty($feedList)  ||  !is_array($feedList)) return  NULL;
        $commentList    =  array();
        $userName       =  $this->autoUidModel->getUserInfo($feedInfo['uid']);
        foreach ($feedList    as  $feedDetail)
        {
            if (!empty(self::$bodyInfo[$feedDetail['bodyId']]) && is_array(self::$bodyInfo[$feedDetail['bodyId']])){
                $feedDetail['nickname']       =    $userName['nickname'];
                $feedDetail                   =    $this->feedModel->rebuildMeCommentData($feedDetail, self::$bodyInfo[$feedDetail['bodyId']]);
                $commentList[]                =    $feedDetail;
                continue;
            }
            
            $redisDiary =  $this->diaryListModel->getDiaryInfoByBodyId($feedDetail['bodyId']);
            self::$bodyInfo[$feedDetail['bodyId']] = $redisDiary;
            
            if (!empty($feedList) || is_array($redisDiary)){
                $feedDetail['nickname']       =    $userName['nickname'];
                $feedDetail                   =    $this->feedModel->rebuildMeCommentData($feedDetail, $redisDiary);
                $commentList[]                =    $feedDetail;
                continue;
            }
            $feedDetail                       =    $this->feedModel->rebuildMeCommentData($feedDetail);
            $commentList[]                    =    $feedDetail;
            
        }
        return  $commentList;
    }/*}}}*/

    public function removeFeed($feedInfo)/*{{{*/
    {
        if (empty($feedInfo['uid']) ||  empty($feedInfo['id']))
        {
            AC::$errorNo    =   'FEC008';
            return  FALSE;
        }
        $result =   $this->feedModel->removeFeed($feedInfo);
        return  $result;
    }/*}}}*/

    private function getFeedDetail($feedInfo)/*{{{*/
    {
        $checkType  =   $this->checkFeedSubtype($feedInfo['type']);
        if ($checkType)
            $type   =   $feedInfo['subType'];
        else
            $type   =   $feedInfo['type'];

        $detail =   UK::getDataByBodyid($type, $feedInfo['bodyId'], ' * ');

        if (empty($detail)) $detail =   NULL;
        return  $detail;
    }/*}}}*/

    private function checkFeedSubtype($type)/*{{{*/
    {
        $feedType   =   array(
                            AC::FEED_COMMENT    =>  'commentTimes',
                            AC::FEED_LIKE       =>  'likeTimes',
                            AC::FEED_SHARE      =>  'shareTimes'   
                        );
        if (empty($feedType[$type]))    return  FALSE;

        return  $feedType[$type];
    }/*}}}*/

    private function feedTypeModel($type)/*{{{*/
    {
        $feedType   =   array(
                            AC::FEED_DIARY      =>  'DiaryListModel:getDiaryListInfo',
                            AC::FEED_COMMENT    =>  '',
                            AC::FEED_LIKE       =>  '',
                            AC::FEED_SHARE      =>  '',
                        );
        if (empty($feedType[$type]))    return  NULL;

        list($info['model'], $info['method'])   =   explode(':', $feedType[$type]);
        return  $info;
    }/*}}}*/

    private function countTimes($countInfo)/*{{{*/
    {
        $modelInfo  =   $this->feedTypeModel($countInfo['type']);
        unset($countInfo['type']);

        $object     =   $this->modelObject($modelInfo['model']);
        $countResult=   $object->countTimes($countInfo);
        return  $countResult;
    }/*}}}*/

    private function modelObject($model)/*{{{*/
    {
        if (isset(self::$modelPool[$model]))
        {
            return  self::$modelPool[$model];
        }

        self::$modelPool[$model]    =   new $model();
        return  self::$modelPool[$model];
    }/*}}}*/

    private function feedUserList($feedInfo)/*{{{*/
    {
        $feedType   =   array(
                            AC::FEED_DIARY              =>  'followMe',
                            AC::FEED_FOLLOW             =>  'followMe',
                            AC::FEED_KIT_ANNIVERSARY    =>  'followMe',
                            AC::FEED_KIT_BMI            =>  'followMe',
                            AC::FEED_KIT_MENSES         =>  'followMe',
                            AC::FEED_KIT_NOTE           =>  'followMe',
                            AC::FEED_KIT_SCHEDULE       =>  'followMe',
                            AC::FEED_KIT_TALLYBOOK      =>  'followMe',
                            AC::FEED_COMMENT            =>  'followMe',
                            AC::FEED_LIKE               =>  'followMe',
                            AC::FEED_SHARE              =>  'followMe',
                            AC::FEED_REPOST             =>  'followMe',
                        );
        if (empty($feedType[$feedInfo['type']]))
        {
            AC::$errorNo    =   'FEC004';
            return  FALSE;
        }

        return  $this->$feedType[$feedInfo['type']]($feedInfo);
    }/*}}}*/

    private function followMe($feedInfo)/*{{{*/
    {
        $info   =   array('uid' => $feedInfo['uid']);
        $list   =   $this->followModel->getFollowMeList($info);
        $follow =   array();
        foreach ($list  as  $value)
        {
            $follow[$value['fUid']] =   $value['status'];
        }
        if (!empty($feedInfo['rUid']))
        {
            $follow[$feedInfo['rUid']]  =   AC::FOLLOW_STATUS_NORMAL;
        }

        if ($feedInfo['uid'] == $feedInfo['authorUid']) return  $follow;

        $follow[$feedInfo['authorUid']] =   AC::FOLLOW_STATUS_NORMAL;
        return  $follow;
    }/*}}}*/

    # include comment, like, share 
    private function eventFeedUserList($feedInfo)/*{{{*/
    {
        $follow =   array();
        if ($feedInfo['uid'] == $feedInfo['authorUid']) return  $follow;

        $follow[$feedInfo['authorUid']] =   AC::FOLLOW_STATUS_NORMAL;
        return  $follow;
    }/*}}}*/

    private function comment($feedInfo)/*{{{*/
    {
        $info   =   array('uid' => $feedInfo['uid']);
        $list   =   $this->followModel->getFollowMeList($info);
        return  $list;
        #   $follow =   array();
        #   foreach ($list  as  $value)
        #   {
        #       $follow[$value['fUid']] =   $value['status'];
        #   }
        #   return  $follow;
    }/*}}}*/

    private function like($feedInfo)/*{{{*/
    {
        $info   =   array('uid' => $feedInfo['uid']);
        $list   =   $this->followModel->getFollowMeList($info);
        return  $list;
        #   $follow =   array();
        #   foreach ($list  as  $value)
        #   {
        #       $follow[$value['fUid']] =   $value['status'];
        #   }
        #   return  $follow;
    }/*}}}*/

    private function share($feedInfo)/*{{{*/
    {
        $info   =   array('uid' => $feedInfo['uid']);
        $list   =   $this->followModel->getFollowMeList($info);
        return  $list;
        #   $follow =   array();
        #   foreach ($list  as  $value)
        #   {
        #       $follow[$value['fUid']] =   $value['status'];
        #   }
        #   return  $follow;
    }/*}}}*/
  
}

